import warnings
from pex import toml
import pymysql
import sqlalchemy as sa
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy.sql import func
from contextlib import contextmanager

from logger import logger

LOGGER = logger.CustomLogger()

TDD_STATUS = "pr_status"
STRENGTHEN_STATUS = "strengthen_status"
CFG = toml.load('config.toml')
# 数据库连接配置
DB_USER = CFG.get("database", {}).get("user")
DB_PASS = CFG.get("database", {}).get("password")
DB_HOST = CFG.get("database", {}).get("host")
DB_NAME = CFG.get("database", {}).get("db_name")

engine = sa.create_engine(f"mysql+pymysql://{DB_USER}:{DB_PASS}@{DB_HOST}/{DB_NAME}?charset=utf8mb4")
# 会话工厂配置
Session = sessionmaker(bind=engine, expire_on_commit=False)
# 声明式基类
Base = declarative_base()


@contextmanager
def session_scope():
    """提供事务范围的上下文管理器"""
    session = Session()
    try:
        yield session
        session.commit()
    except Exception as e:
        session.rollback()
        raise
    finally:
        session.close()


class DatabaseManager:
    def __init__(self):
        self.connection = pymysql.connect(
            host=DB_HOST,
            user=DB_USER,
            password=DB_PASS,
            database=DB_NAME,
            charset='utf8mb4',
            use_unicode=True
        )
        self.cursor = self.connection.cursor()

    def init_db(self):
        # 本地MySQL连接配置
        Base.metadata.create_all(engine)
        LOGGER.info("[sys] 数据库初始化成功！")

    def drop_table(self, table_name):
        """安全清空单个表"""
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            self.cursor.execute("SET FOREIGN_KEY_CHECKS = 0")
            self.cursor.execute(f"DROP TABLE IF EXISTS `{table_name}`")
            self.cursor.execute("SET FOREIGN_KEY_CHECKS = 1")
        LOGGER.info(f"[sys] 表 {table_name} 已清空")

    def clean_database(self):
        self.drop_table("pull_request_infos")
        self.drop_table("pr_event_force_status")
        self.drop_table("pr_code_owners")
        LOGGER.info(f"[sys] 数据库 {self.connection.db.decode()} 的表已清空")

    def __del__(self):
        if self.connection:
            self.connection.close()


# pr基本信息
class PullRequestInfos(Base):
    __tablename__ = "pull_request_infos"
    id = sa.Column(sa.String(36), primary_key=True)
    pr_number = sa.Column(sa.String(16))
    repo_owner = sa.Column(sa.String(128))
    repo_name = sa.Column(sa.String(128))
    branch = sa.Column(sa.String(128))
    author = sa.Column(sa.String(128))
    merged = sa.Column(sa.Boolean, default=False)
    created_at = sa.Column(sa.DateTime(timezone=True), nullable=False, server_default=func.now())
    merged_at = sa.Column(sa.DateTime)
    force_pass = sa.Column(sa.Boolean, default=False)  # 一路绿灯，全部放行
    force_account = sa.Column(sa.String(128))
    forced_at = sa.Column(sa.DateTime)


class PrEventForceStatus(Base):
    __tablename__ = "pr_event_force_status"
    id = sa.Column(sa.String(36), primary_key=True)
    event_name = sa.Column(sa.String(128), primary_key=True)
    force_pass = sa.Column(sa.Boolean, default=False)  # 单event放行
    force_account = sa.Column(sa.String(128))
    forced_at = sa.Column(sa.DateTime, server_default=func.now(), onupdate=func.now(), nullable=False)


class PrCodeOwners(Base):
    __tablename__ = "pr_code_owners"
    id = sa.Column(sa.String(36), primary_key=True)
    owner_name = sa.Column(sa.String(128), primary_key=True)
